﻿using Chaunce.FrameWork.NetCore.Chaunce.Utility.Helpers;
using Chaunce.FrameWork.NetCore.SysCore.Consts;
using Chaunce.Web.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Policy;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Chaunce.Web.Core.Filters
{
    /// <summary>
    /// 自定义认证过滤器 重写401 403返回值
    /// </summary>
    public class CustomAuthorizeFilter : IAsyncAuthorizationFilter
    {
        public AuthorizationPolicy Policy { get; }

        public CustomAuthorizeFilter(AuthorizationPolicy policy)
        {
            Policy = policy ?? throw new ArgumentNullException(nameof(policy));
        }

        public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            // 过滤匿名访问
            if (context.Filters.Any(item => item is IAllowAnonymousFilter))
            {
                return;
            }

            var policyEvaluator = context.HttpContext.RequestServices.GetRequiredService<IPolicyEvaluator>();
            var authenticateResult = await policyEvaluator.AuthenticateAsync(Policy, context.HttpContext);
            var authorizeResult = await policyEvaluator.AuthorizeAsync(Policy, authenticateResult, context.HttpContext, context);

            if (!authorizeResult.Succeeded)
            {
                context.HttpContext.Response.StatusCode = 200;
                context.HttpContext.Response.ContentType = "application/json";
                string errorMsg = "未授权访问,请重新登陆!";
                context.Result = errorMsg.ToErrorActionResult(AppErrorCode.Unauthorization.ToInt());
            }
            else
            {
                //TODO 到SSO中心验证token是否失效
                string token = context.HttpContext.Request.Headers["Authorization"];
            }
        }
    }
}
